package com.itheima.userservice.elasticsearch;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.userservice.bean.HotelConstants;
import com.itheima.userservice.bean.UserBean;
import com.itheima.userservice.config.ElasticSearchConfig;
import com.itheima.userservice.service.ElasticSearchService;
import org.bouncycastle.cert.ocsp.Req;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;

import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/es")
public class ElasticSearchController {

    @Autowired
    private ElasticSearchService searchServiceImpl;

    @Autowired
    private ElasticSearchConfig client;

    //todo::某种未知的原因导致创建一直会报错
    @PostMapping("/addIndex")
    public void addIndex(@RequestBody String s) throws IOException {
//        BulkRequest bulkRequest = new BulkRequest();
//
//        String addList = (String) map.get("addList");
//        int row = searchServiceImpl.addList(addList);

        //todo::目前通过代码创建会有bug

        System.out.println(s);
        CreateIndexRequest myIndex = new CreateIndexRequest("my_index001");
        myIndex.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
        client.restHighLevelClient().indices().create(myIndex, RequestOptions.DEFAULT);

    }

    @GetMapping("/getIndex")
    public Map<String, Object> getIndex() throws IOException {
        // 1.创建Request对象
        GetIndexRequest request = new GetIndexRequest("user_index");
        // 2.发送请求
        boolean exists = client.restHighLevelClient().indices().exists(request, RequestOptions.DEFAULT);
        // 3.输出
        Map<String, Object> hashMap = new HashMap<>();
        if (exists) {
            hashMap.put("success", "索引库已经存在！");
        } else {
            hashMap.put("error", "索引库不存在！");
        }
        return hashMap;
    }

//    @PostMapping("/getOne")
//    public Map<String, Object> getOne(@RequestBody Map<String, Object> map) throws IOException {
//        //type类型默认是_doc,因为es7x版本之后就只有一个默认的_doc类型
//        //创建request对象
//        GetRequest request = new GetRequest((String) map.get("index"), (String) map.get("id"));
//        //发送请求
//        GetResponse documentFields = client.restHighLevelClient().get(request, RequestOptions.DEFAULT);
//        //解析结果
//        String sourceAsString = documentFields.getSourceAsString();
//        System.out.println("获取到的结果 === > " + sourceAsString);
//        ObjectMapper objectMapper = new ObjectMapper();
//        JsonNode jsonNode = objectMapper.readTree(sourceAsString);
//        System.out.println("转转的结果 === > " + jsonNode);
//
//        Map<String, Object> hashMap = new HashMap<>();
//        hashMap.put("ok", jsonNode);
//        return hashMap;
//    }

//    @PostMapping("/deleteOne")
//    public Map<String, Object> deleteOne(@RequestBody Map<String, Object> map) throws IOException {
//        Map<String, Object> hashMap = new HashMap<>();
//        //创建request对象
//        DeleteRequest deleteRequest = new DeleteRequest((String) map.get("index"), (String) map.get("id"));
//
//        //发送请求
//        DeleteResponse delete = client.restHighLevelClient().delete(deleteRequest, RequestOptions.DEFAULT);
//
//        System.out.println("删除结果 === > " + delete.status());
//        //根据状态来判断删除结果的,200表示成功  404表示删除失败
//        int status = delete.status().getStatus();
//        if (status == 200) {
//            hashMap.put("success", "doc中id为" + map.get("id") + "删除成功");
//        } else {
//            hashMap.put("error", "doc中id为" + map.get("id") + "删除失败");
//        }
//        return hashMap;
//    }

//    @PostMapping("/update")
//    public Map<String, Object> update(@RequestBody Map<String,Object> map) throws IOException {
//        UpdateRequest request = new UpdateRequest("user_index", (String) map.get("id"));
//        Map<String, Object> hashMap = new HashMap<>();
//
//        request.doc(map);
//
//        UpdateResponse update = client.restHighLevelClient().update(request, RequestOptions.DEFAULT);
//        int status = update.status().getStatus();
//        if (status == 200) {
//            hashMap.put("success", "doc中id为" + map.get("id") + "修改成功");
//        } else {
//            hashMap.put("error", "doc中id为" + map.get("id") + "修改失败");
//        }
//        return hashMap;
//    }

    //查询该索引的全部doc
    @PostMapping("/query/1")
    public Map<String,Object> query_1() throws IOException {
        SearchRequest request = new SearchRequest("user_index");
        request.source().query();
        SearchResponse search = client.restHighLevelClient().search(request, RequestOptions.DEFAULT);
        System.out.println(search);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("return",search);
        return hashMap;
    }

    //多种情况写在一起了
    @PostMapping("/query/2")
    public Map<String,Object> query_2() throws IOException {
        SearchRequest request1 = new SearchRequest("user_index");
        //查询根据某一个字段查询
        request1.source().query(QueryBuilders.matchQuery("address","桂林"));
        SearchResponse search1 = client.restHighLevelClient().search(request1, RequestOptions.DEFAULT);
        System.out.println(search1);

        System.out.println("=============================");

        //查询精准查询
        SearchRequest request2 = new SearchRequest("user_index");
        //todo::精准匹配桂林市的时候就出现null的情况,莫名其妙的bug;匹配别的字段就可以
        request2.source().query(QueryBuilders.termQuery("address","桂林市"));
        SearchResponse search2 = client.restHighLevelClient().search(request2, RequestOptions.DEFAULT);
        System.out.println(search2);

        System.out.println("=============================");

        //布尔查询
        SearchRequest request3 = new SearchRequest("user_index");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("name","zhangsan"));
        //过滤结果  range就是范围的意思
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("id").gt(1));
        request3.source().query(boolQueryBuilder);

        SearchResponse search3 = client.restHighLevelClient().search(request3, RequestOptions.DEFAULT);
        System.out.println(search3);

        System.out.println("=============================");

        //分页、排序
        SearchRequest request4 = new SearchRequest("user_index");
        request4.source().query(QueryBuilders.matchAllQuery());
        //排序 asc是升序  desc是降序
        request4.source().sort("id", SortOrder.ASC);
        request4.source().sort(SortBuilders.geoDistanceSort("id",new GeoPoint()));
        // 页码，每页大小
        int page = 1, size = 2;
        request4.source().from((page - 1) * size).size(2);
        SearchResponse search4 = client.restHighLevelClient().search(request4, RequestOptions.DEFAULT);
        System.out.println(search4);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("return1",search1);
        hashMap.put("return2",search2);
        hashMap.put("return3",search3);
        return hashMap;
    }

    @PostMapping("/highLight")
    public Map<String,Object> highLight() throws IOException {
        SearchRequest request = new SearchRequest("user_index");
        request.source().query(QueryBuilders.matchQuery("name","ww"));
        request.source().highlighter(new HighlightBuilder().field("address").requireFieldMatch(false));
        SearchResponse search = client.restHighLevelClient().search(request, RequestOptions.DEFAULT);

        System.out.println(search);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("return",search);
        return hashMap;
    }
}
